package com.iflytek.jzcpx.procuracy.card.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.iflytek.jzcpx.procuracy.card.dao.CardFormFieldDao;
import com.iflytek.jzcpx.procuracy.card.entity.CardFile;
import com.iflytek.jzcpx.procuracy.card.entity.CardFormField;
import com.iflytek.jzcpx.procuracy.card.service.CardFileService;
import com.iflytek.jzcpx.procuracy.card.service.CardFormFieldService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

/**
 * @author <a href=mailto:ktyi@iflytek.com>伊开堂</a>
 * @date 2019-08-27 10:18
 */
@Service
public class CardFormFieldServiceImpl extends ServiceImpl<CardFormFieldDao, CardFormField>
        implements CardFormFieldService {
    private static final Logger logger = LoggerFactory.getLogger(CardFormFieldServiceImpl.class);

    @Autowired
    private CardFileService cardFileService;

    @Override
    public Map<Long, List<CardFormField>> findFieldsByFileId(List<Long> fileIds) {
        if (CollectionUtils.isEmpty(fileIds)) {
            return new HashMap<>();
        }

        QueryWrapper<CardFormField> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(CardFormField::getCardFileId, fileIds);
        List<CardFormField> fields = list(wrapper);
        if (CollectionUtils.isEmpty(fields)) {
            return new HashMap<>();
        }

        return fields.stream().collect(Collectors.groupingBy(CardFormField::getCardFileId));
    }

    @Override
    public boolean removeByCardFileIds(List<Long> cardFileIds) {
        if (CollectionUtils.isEmpty(cardFileIds)) {
            return false;
        }

        QueryWrapper<CardFormField> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(CardFormField::getCardFileId, cardFileIds);
        return remove(wrapper);
    }

    @Override
    public boolean updateBdjgId(List<Long> ids, String bdjgId) {
        if (CollectionUtils.isEmpty(ids) || StringUtils.isBlank(bdjgId)) {
            return false;
        }

        CardFormField entity = new CardFormField();
        entity.setBdjgId(bdjgId);

        QueryWrapper<CardFormField> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(CardFormField::getId, ids);

        logger.info("根据id批量更新bdjgId字段, ids[ {} ], bdjgId[ {} ]", Joiner.on(", ").join(ids), bdjgId);
        return update(entity, wrapper);
    }

    @Override
    public Map<CardFile, List<CardFormField>> listFieldsForDiff(String bmsah, String stbm, String stzd, String bdjgId) {
        Map<CardFile, List<CardFormField>> result = new HashMap<>();

        List<CardFile> cardFiles = cardFileService.listByBmsah(bmsah);
        if (CollectionUtils.isEmpty(cardFiles)) {
            return result;
        }

        Map<Long, CardFile> cardFileMap = cardFiles.stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
        QueryWrapper<CardFormField> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(CardFormField::getCardFileId, cardFileMap.keySet()).eq(CardFormField::getStbm, stbm)
               .eq(CardFormField::getZdmc, stzd).eq(CardFormField::getBdjgId, bdjgId);
        List<CardFormField> cardFormFields = list(wrapper);
        if (CollectionUtils.isEmpty(cardFormFields)) {
            return result;
        }

        Map<Long, List<CardFormField>> fieldsOfFileMap = cardFormFields.stream().collect(
                Collectors.groupingBy(CardFormField::getCardFileId));
        for (Map.Entry<Long, List<CardFormField>> entry : fieldsOfFileMap.entrySet()) {
            Long cardFileId = entry.getKey();
            List<CardFormField> formFields = entry.getValue();

            CardFile cardFile = cardFileMap.get(cardFileId);
            List<CardFormField> fields = result.getOrDefault(cardFile, new ArrayList<>());
            fields.addAll(formFields);

            result.put(cardFile, fields);
        }

        return result;
    }

    @Override
    public int cleanData(Date startDatetime, Date endDatetime) {
        logger.info("清理cardFormField数据, 起止时间: {} - {}", startDatetime, endDatetime);
        Assert.isTrue(startDatetime != null || endDatetime != null, "开始和结束时间不能同时为空");

        int cleanCount = 0;

        List<CardFormField> cardFormFields = null;
        int pageSize = 2;
        do {
            Page<CardFormField> page = new Page<>(1, pageSize);
            LambdaQueryWrapper<CardFormField> wrapper = new LambdaQueryWrapper<>();
            if (startDatetime != null) {
                wrapper.gt(CardFormField::getCreateTime, startDatetime);
            }
            if (endDatetime != null) {
                wrapper.lt(CardFormField::getCreateTime, endDatetime);
            }
            IPage<CardFormField> cardFormFieldPage = this.baseMapper.selectPage(page, wrapper);
            if (cardFormFieldPage == null || CollectionUtils.isEmpty(cardFormFieldPage.getRecords())) {
                logger.info("没有待清理的cardFormField数据了");
                return cleanCount;
            }

            cardFormFields = cardFormFieldPage.getRecords();
            logger.debug("查询到待清理的cardFormField数据, size: {}, page: {}", cardFormFields.size(), page);

            for (CardFormField cardFormField : cardFormFields) {
                logger.info("删除cardFormField数据, cardFormField: {}", cardFormField);
                if (removeById(cardFormField)) {
                    cleanCount++;
                }
            }
        } while (CollectionUtils.size(cardFormFields) >= pageSize);

        return cleanCount;
    }
}
